// StoreNumeri.cpp: definisce le funzioni esportate per l'applicazione DLL.
//

#include "stdafx.h"
#include "StoreNumeri.h"

STORENUMERI_API double pi=3.14159265359;
STORENUMERI_API double nepero=2.71828182846;
STORENUMERI_API int zero=0;
STORENUMERI_API int uno=1;

STORENUMERI_API double CALLBACK getSin(double a)
{
	return sin(a);
}

STORENUMERI_API double CALLBACK getCos(double a)
{
	return cos(a);
}

STORENUMERI_API double CALLBACK getTan(double a)
{
	return tan(a);
}

STORENUMERI_API double CALLBACK getExp(double a)
{
	return pow(nepero,a);
}

STORENUMERI_API double CALLBACK getPi()
{
	return pi;
}

STORENUMERI_API double CALLBACK getNepero()
{
	return nepero;
}

STORENUMERI_API int CALLBACK getZero()
{
	return zero;
}

STORENUMERI_API int CALLBACK getUno()
{
	return uno;
}

STORENUMERI_API void CALLBACK calcArrayInt(int *m, int l)
{
	for (int i=0; i < l; i++)
		m[i]=1-2*m[i];
}

STORENUMERI_API void CALLBACK calcArrayDouble(double *m, int l)
{
	for (int i=0; i < l; i++)
		m[i]=pow(nepero,m[i]);
}

//DEPRECATO: usare i SAFEARRAY e la classe di manipolazione CComSafeArray
//Per il passaggio di una matrice si utilizza un array, viene istanziata una riga dietro l'altra
//
//Esempio: |1 3| matrice 2*2   =>   [1 3 2 4] array passato
//		   |2 4|
//
//Leggere la matrice come in c/c++ considerando lo scorrimento degli indici:
//	i=indice di lettura di colonna
//	j=indice di lettura di riga
//	n=dimensione colonne
//1)Lettura e scrittura su array, 2 cicli "for" con indici "i" e "j"=> Array[i+n*j]
//2)Lettura su array e scrittura su matrice o viceversa, 1 ciclo "for" con indice "i" => Matrice[i%n][i/n] :: Array[i]		
STORENUMERI_API void CALLBACK calcMatInt(int *mm, int n, int m)
{
	int k=0;
	for (int i=0; i < n; i++)
		for (int j=0; j < m; j++)
			mm[i+n*j]=1-2*mm[i+n*j];

}

STORENUMERI_API void CALLBACK calcMatDouble(double *mm, int n, int m)
{
	for (int i=0; i < n; i++)
		for (int j=0; j < m; j++)
			mm[i+n*j]=pow(nepero,mm[i+n*j]);
}

//DEPRECATO: usare i SAFEARRAY e la classe di manipolazione CComSafeArray
//Le funzioni di conversione servono nel caso in cui, nell'utilizzo di una
//libreria esterna che ha come parametro un doppio puntatore, matrice, deve
//essere passata la matrice di VBA
STORENUMERI_API void CALLBACK calcMatIntC(int *mm, int n, int m)
{
	int **M;
	
	//Istanziazione della matrice
	M=new int *[n];
	for(int i=0; i < n; i++)
		M[i]=new int[m];

	//Conversione dall'array alla matrice
	//Meglio usare questo metodo, un "for" in meno
	for (int i=0; i < n*m; i++)
		M[i%n][i/n]=mm[i];

	//TODO: inserire la funzione che passa la matrice M estratta
	
	//Conversione dalla matrice all'array
	//Meglio usare questo metodo, un "for" in meno
	for (int i=0; i < n*m; i++)
		mm[i]=M[i%n][i/n];

	//Liberazione della memoria
	for(int i=0; i < n; i++)
		delete []M[i];
	delete []M;

}

STORENUMERI_API void CALLBACK calcMatDoubleC(double *mm,int n,int m)
{
	double **M;
	
	M=new double *[n];
	for(int i=0; i < n; i++)
		M[i]=new double[m];

	for (int i=0; i < n*m; i++)
		M[i%n][i/n]=mm[i];

	//TODO: inserire la funzione che passa la matrice M estratta
	
	for (int i=0; i < n*m; i++)
		mm[i]=M[i%n][i/n];

	for(int i=0; i < n; i++)
		delete []M[i];
	delete []M;
}

STORENUMERI_API int CALLBACK sumArrayInt(int *mm, int l)
{
	int sum = 0;
	for(int i = 0; i < l; i++)
		sum += mm[i];
	return sum;
}

STORENUMERI_API double CALLBACK sumArrayDouble(double *mm, int l)
{
	double sum = 0;
	for(int i = 0; i < l; i++)
		sum += mm[i];
	return sum;
}